﻿Imports System.Collections.ObjectModel

Public MustInherit Class BusinessBase(Of T As IEntity)
    Implements IEntity

    Private _brokenRules As New List(Of BrokenRule)
    Private _ID As Guid = Guid.Empty

    Public Property Id() As System.Guid Implements IEntity.Id
        Get
            Return _ID
        End Get
        Private Set(ByVal value As System.Guid)
            _ID = value
        End Set
    End Property

#Region "Equality Overrides"

    Public Overrides Function Equals(ByVal obj As Object) As Boolean

        If Not obj Is Nothing AndAlso obj.GetType Is GetType(T) Then

            If Me.hasSameIdentifierAs(CType(obj, T)) Then
                ' Both entities are persistant so we are able to 
                ' compare the identifiers
                Return True

            ElseIf hasDifferentPersistanceContextAs(CType(obj, T)) Then
                ' One entity is transient one is persistant so that cannot
                ' be eqaul
                Return False
            Else
                ' Neither Entity has an Identity
                Return False
            End If

        End If
    End Function

    Protected Function IsTransient() As Boolean Implements IEntity.IsTransient
        Return Me.Id = Guid.Empty
    End Function

    Private Function hasSameIdentifierAs(ByVal EntityToCompare As T) As Boolean
        If Not (IsTransient() And EntityToCompare.IsTransient) Then
            Return Me.Id = EntityToCompare.Id
        Else
            Return False
        End If
    End Function

    Public Overrides Function GetHashCode() As Integer
        If IsTransient() Then
            Return Me.GetType.FullName.GetHashCode
        Else
            Return String.Format("{0}{1}", _
             Me.GetType.FullName, Id.ToString).GetHashCode
        End If
    End Function


    Private Function hasDifferentPersistanceContextAs(ByVal EntityToCompare As T) As Boolean
        Return Not (IsTransient() = EntityToCompare.IsTransient)
    End Function

#End Region

#Region "Entity Validation"

    Protected MustOverride Sub validate()

    Protected ReadOnly Property BrokenRules() As List(Of BrokenRule)
        Get
            Return Me._brokenRules
        End Get
    End Property

    Public Function GetBrokenRules() As ReadOnlyCollection(Of BrokenRule)
        Me.BrokenRules.Clear()
        Me.validate()
        Return Me._brokenRules.AsReadOnly
    End Function

#End Region

End Class
